#include <gtest/gtest.h>
#include <limits.h>

using namespace ::std;

class Solution {
public:
    int myAtoi(string s);
};

// 看清题目要求
// 注意整型的边界，包括计算过程中的中间结果，也要保证不溢出
int Solution::myAtoi(string s) {
    bool findFlag = false; // 遇到正负标记
    bool isNegative = false;
    bool findNum = false;
    int result = 0;
    for(char c : s) {
        if(findNum) {
            int num;
            if(!isdigit(c)) { // 找到数字之后，再看到其他字符就直接结束循环
                break;
            }
            if(isNegative) {
                num = '0' - c;
                // result < INT_MIN / 10 只能保证result * 10不溢出，如果还要加其他数字，则要进行更多检查
                if(result < INT_MIN / 10) {
                    result = INT_MIN;
                    break;
                }
                result = result * 10;
                if(INT_MIN - result > num) { // 看距离最大值的剩余大小，还够不够
                    result = INT_MIN;
                    break;
                }
            } else {
                num = c - '0';
                if(result > INT_MAX / 10) {
                    result = INT_MAX;
                    break;
                }
                result = result * 10;
                if(INT_MAX - result < num) {
                    result = INT_MAX;
                    break;
                }
            }
            result += num;
        } else {
            if(!isdigit(c) && c != '-' && c != '+' && c != ' ') {
                break;
            }
            if(isdigit(c)) {
                findNum = true;
                if(isNegative) {
                    result += '0' - c;
                } else {
                    result += c - '0';
                }
            }
            if(findFlag) {
                // 找到'-' or '+'之后，如果紧接着的字符不是数字也不是'-' or '+'，则退出循环！！
                if(!isdigit(c)) {
                    break;
                }
            } else if(c == '-') {
                findFlag = true;
                isNegative = true;
            } else if(c =='+') {
                findFlag = true;
            }
        }
    }
    return result;
}

class MyAtoiCheck : public ::testing::Test {
public:
	class Solution solution;
};

TEST_F(MyAtoiCheck, testMyAtoi_1) {
    string s = "   -42";
    EXPECT_TRUE(-42 == solution.myAtoi(s));
}

TEST_F(MyAtoiCheck, testMyAtoi_2) {
    string s = "  6--- 2sdf";
    EXPECT_TRUE(6 == solution.myAtoi(s));
}

TEST_F(MyAtoiCheck, testMyAtoi_3) {
    string s = "  66666666666666--- 2sdf";
    EXPECT_TRUE(INT_MAX == solution.myAtoi(s));
}

TEST_F(MyAtoiCheck, testMyAtoi_4) {
    string s = "  -66666666666666--- 2sdf";
    EXPECT_TRUE(INT_MIN == solution.myAtoi(s));
}

TEST_F(MyAtoiCheck, testMyAtoi_5) {
    string s = "sdf  -6666--- 2sdf";
    EXPECT_TRUE(0 == solution.myAtoi(s));
}

TEST_F(MyAtoiCheck, testMyAtoi_6) {
    string s = "+ 6666--- 2sdf";
    EXPECT_TRUE(0 == solution.myAtoi(s));
}

TEST_F(MyAtoiCheck, testMyAtoi_7) {
    string s = "   +666--- 2sdf";
    EXPECT_TRUE(666 == solution.myAtoi(s));
}

TEST_F(MyAtoiCheck, testMyAtoi_8) {
    string s = "   -00666--- 2sdf";
    EXPECT_TRUE(-666 == solution.myAtoi(s));
}

TEST_F(MyAtoiCheck, testMyAtoi_9) {
    string s = "   ";
    EXPECT_TRUE(0 == solution.myAtoi(s));
}

TEST_F(MyAtoiCheck, testMyAtoi_10) { // 中间结果如果溢出，这里测不出来，LeetCode就可以，可能是编译器版本的原因
    string s = "21474836460";
    EXPECT_TRUE(2147483647 == solution.myAtoi(s));
}

TEST_F(MyAtoiCheck, testMyAtoi_11) {
    string s = "2147483648";
    EXPECT_TRUE(2147483647 == solution.myAtoi(s));
}

int main() {
	::testing::InitGoogleTest();
	return RUN_ALL_TESTS();
}
